package restaurant;

/**
 * Reports class.
 * 
 * @author MSM41 SG350, CT267.
 */
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;

public class Reports {

	/** Instance Variables */
	private ArrayList<OrderItem> orderList = null;
	private TreeSet<MenuItem> treeSet = null;

	/** For Frequency Report */
	private TreeMap<String, Integer> frequencyDetails = null;
	private TreeSet<String> dishesNotOrdered = null;

	public Reports(ArrayList<OrderItem> oi, TreeSet<MenuItem> mi) {
		if( oi==null &&mi==null ){
			throw new IllegalArgumentException("Data structure is Empty");
		}else{
			orderList = new ArrayList<OrderItem>();
			treeSet = new TreeSet<MenuItem>();
			orderList = oi;
			treeSet = mi;
			frequencyDetails = new TreeMap<String, Integer>();
			dishesNotOrdered = new TreeSet<String>();
			createFrequencyReport();
		}
	
	}

	/**
	 * Returns true if word contains letters , false otherwise
	 * 
	 * @return newWord
	 */
	public String removeNonAlpha(String word) {
		String newWord = "";
		for (int count = 0; count < word.length(); count++) {
			char ch = word.charAt(count);
			if ((ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z')) {
				newWord += ch;
			}
		}
		return newWord;
	}

	/**
	 * Add the names of menu items ordered and their quantity for frequency
	 * report.
	 */
	public void populateFrequencyReport(String word, int quantity) {
		/* Remove non-alpha characters, return if now empty */
		String strippedWord = removeNonAlpha(word);
		if (strippedWord.length() == 0)
			return;
		/*
		 * If a particular menu item does not exist in TreeSet, add a new entry
		 * in TreeMap else update the quantity key.
		 */
		if (!frequencyDetails.containsKey(strippedWord)) {
			frequencyDetails.put(strippedWord, quantity);
		} else {
			int oldQuantity = frequencyDetails.get(strippedWord);
			frequencyDetails.put(strippedWord, quantity + oldQuantity);
		}
	}

	/**
	 * Read items ordered for frequency report from the OrderItem ArrayList and
	 * get their name and quantity Also check for any items not ordered from
	 * menu.
	 */
	public void createFrequencyReport() {
		for (OrderItem o : orderList) {
			populateFrequencyReport(o.getName(), o.getQuantity());
		}
	}

	/**
	 * Prints each entry from the frequencyReport, one per line.
	 * 
	 * @return output
	 */
	public String getFrequecyReport() {

		Set<Map.Entry<String, Integer>> entries = frequencyDetails.entrySet();

		String output = ("=============FREQUENCY REPORT=============\n");
		/**
		 * For each entry get and print the menu item (the key) get and print
		 * the number of times this menu item is ordered (the value)
		 */
		for (Map.Entry<String, Integer> entry : entries) {

			/* Get and print menu item */
			String menuItem = entry.getKey().toUpperCase();
			output += (String.format("%-12s", menuItem) + " ");

			int quantity = entry.getValue();
			output += (quantity + "\n");
		}
		return output;
	}
	
	/**
	 * Prints each food dish not ordered from dishNotOrdered method.
	 * 
	 * @return output
	 */
	public String getDishesNotOrdered() {
		String output = ("=============DISHES NOT ORDERED==============\n");
		/* Iterating over the Tree set data */
		for (MenuItem mi : treeSet) {
			if (!frequencyDetails.containsKey(mi.getDish())) {
				dishesNotOrdered.add(mi.getDish());
			}
		}

		Iterator<String> iterator = dishesNotOrdered.iterator();
		/* Displaying the Tree set data */
		while (iterator.hasNext()) {
			output += (iterator.next().toUpperCase() + "\n");
		}
		return output;
	}

}
